package com.anivia.common.web.config.dataScope;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.druid.support.spring.stat.annotation.Stat;
import com.anivia.common.core.constant.TableFieldConstant;
import com.anivia.common.core.enums.DataScopeEnum;
import com.anivia.common.web.model.vo.DataScopeVO;
import com.anivia.common.web.privoder.DataHandlerProvider;
import com.anivia.common.web.satoken.util.UserInfoUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import java.util.*;

/**
 * 数据权限上下文
 *
 * @author wangj
 */

@Slf4j
public class DataScopeContext {

    private static final ThreadLocal<DataScopeVO> DATA_SCOPE = new InheritableThreadLocal<>();

    /**
     * 开启数据权限，使用默认字段
     * 部门id：dept_id
     * 创建人：creator_id
     *
     * @param resourceId 资源id
     */
    public static void start(Integer resourceId) {
        startCustom(resourceId, null);
    }

    /**
     * 开启数据权限，使用自定义字段名称
     *
     * @param resourceId 资源id
     * @param fieldName  自定义字段名称
     */
    public static void start(Integer resourceId, FieldName fieldName) {
        if (fieldName == null
                || (StrUtil.isBlank(fieldName.getDeptIdFieldName())) && StrUtil.isBlank(fieldName.getUserIdFieldName())) {
            startCustom(resourceId, null);
        } else {
            startCustom(resourceId, fieldName);
        }
    }

    /**
     * 开启数据权限，使用默认字段
     * 部门id：dept_id
     * 创建人：creator_id
     *
     * @param resourceId 资源id
     */
    private static void startCustom(Integer resourceId, FieldName fieldName) {
        DataScopeVO dataScopeVO = new DataScopeVO();
        dataScopeVO.setOpenScope(true);
        DataHandlerProvider provider = null;
        try {
            provider = SpringUtil.getBean(DataHandlerProvider.class);
        } catch (NoSuchBeanDefinitionException e) {
            throw new RuntimeException("当前服务未实现DataHandlerProvider，数据权限功能无法使用。");
        }
        // 通过资源查询数据权限范围
        List<DataScopeEnum> dataScopeList = provider.getDataScopeByResource(resourceId);
        if (CollUtil.isEmpty(dataScopeList)) {
            log.info("未查询到数据权限范围，无权查看数据！");
            dataScopeVO.setHasDataScope(false);
        } else {
            dataScopeVO.setDataScope(dataScopeList);
            // 如果有全公司的权限，则直接关闭数据权限功能
            if (dataScopeList.contains(DataScopeEnum.ALL)) {
                dataScopeVO.setOpenScope(false);
            } else {
                Map<String, Set<Integer>> dataScopeItem = new HashMap<>();
                Set<Integer> deptIds = new HashSet<>();
                Integer userId = UserInfoUtil.getLoginUserId();

                for (DataScopeEnum dataScopeEnum : dataScopeList) {
                    switch (dataScopeEnum) {
                        case DEPT_AND_SUB -> {
                            Integer deptId = provider.getDeptIdByLoginUser();
                            deptIds.add(deptId);

                            Set<Integer> subDeptIds = provider.getSubDeptIds(deptId);
                            if (CollUtil.isNotEmpty(subDeptIds)) {
                                deptIds.addAll(subDeptIds);
                            }
                        }
                        case DEPT -> {
                            Integer deptId = provider.getDeptIdByLoginUser();
                            deptIds.add(deptId);
                        }
                        case SELF -> {
                            if (fieldName != null && fieldName.getUserIdFieldName() != null) {
                                dataScopeItem.put(fieldName.getUserIdFieldName(), Set.of(userId));
                            } else {
                                dataScopeItem.put(TableFieldConstant.CREATOR_ID_FIELD, Set.of(userId));
                            }
                        }
                        case CUSTOM_DEPT -> {
                            Set<Integer> customDeptIds = provider.getCustomDeptIds(resourceId);
                            if (CollUtil.isNotEmpty(customDeptIds)) {
                                deptIds.addAll(customDeptIds);
                            }
                        }
                        case SUB_DEPT -> {
                            Integer deptId = provider.getDeptIdByLoginUser();
                            Set<Integer> subDeptIds = provider.getSubDeptIds(deptId);
                            if (CollUtil.isNotEmpty(subDeptIds)) {
                                deptIds.addAll(subDeptIds);
                            }
                        }
                        default -> {
                        }
                    }
                }
                if (fieldName != null && fieldName.getDeptIdFieldName() != null) {
                    dataScopeItem.put(fieldName.getDeptIdFieldName(), deptIds);
                } else {
                    dataScopeItem.put(TableFieldConstant.DEPT_ID_FIELD, deptIds);
                }

                dataScopeVO.setDataScopeItem(dataScopeItem);
            }
        }
        DATA_SCOPE.set(dataScopeVO);
    }

    /**
     * 关闭数据权限
     */
    public static void close() {
        DATA_SCOPE.remove();
    }

    /**
     * 查询配置
     */
    public static DataScopeVO get() {
        if (DATA_SCOPE.get() == null) {
            DataScopeVO dataScopeVO = new DataScopeVO();
            // 默认未开启数据权限
            dataScopeVO.setOpenScope(false);
            return dataScopeVO;
        }
        return DATA_SCOPE.get();
    }

    @AllArgsConstructor
    @Data
    @NoArgsConstructor
    @Builder
    public static class FieldName {
        /**
         * 部门id字段名称
         */
        private String deptIdFieldName;
        /**
         * 用户id字段名称
         */
        private String userIdFieldName;
    }
}